﻿using Autofac;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Reflection;
using Module = Autofac.Module;
using Autofac.Core;
using Nasty.Core.Model;
using Nasty.Core.Entity;

namespace Nasty.Core.Registry
{
    /// <summary>
    /// 自动注册基类
    /// </summary>
    public abstract class ModuleRegister : Module, IModuleRegister
    {
        public virtual string SwaggerName { get; set; } = string.Empty;

        /// <summary>
        /// 获取所有的IAutofacActionFilter类型
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Type> GetActionFilters()
        {
            var assembly = this.GetType().Assembly;
            return assembly.GetTypes()
                         .Where(t => (typeof(IAutofacActionFilter).IsAssignableFrom(t) || typeof(IAutofacExceptionFilter).IsAssignableFrom(t)) && t.IsClass && !t.IsInterface && !t.IsAbstract)
                         .ToList();
        }

        public Assembly GetAssembly()
        {
            return this.GetType().Assembly;
        }

        public List<Type> GetIBaseEntities()
        {
           return GetAssembly().GetTypes().Where(t => typeof(IBaseEntity).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract && !t.IsInterface)
               .ToList();
        }

        protected override void Load(ContainerBuilder builder)
        {
            var assembly = GetAssembly();

            // 注册所有继承IAutofacRegister
            builder.RegisterAssemblyTypes(assembly)
                .Where(t => typeof(IAutofacRegister).IsAssignableFrom(t) && t != typeof(IAutofacRegister))
                .AsImplementedInterfaces()
                .PropertiesAutowired()
                .InstancePerLifetimeScope();

            // 自动注册所有实现IMiddleware的类型
            builder.RegisterAssemblyTypes(assembly).Where(t => t.IsClass && !t.IsAbstract && typeof(IAutofacMiddleware).IsAssignableFrom(t))
                .AsSelf()
                .As<IMiddleware>()
                .InstancePerLifetimeScope()
                 .PropertiesAutowired();

            // 自动注册所有IAutofacFlowAction 的实现类
            assembly.GetTypes().Where(t => typeof(IAutofacFlowAction).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)
                .ToList()
                .ForEach(type => builder.RegisterType(type)
                .Named<IAutofacFlowAction>($"Flow:{type.Name}")
                .InstancePerLifetimeScope()
                .PropertiesAutowired());


            assembly.GetTypes().Where(t => typeof(IAutofacJob).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)
                .ToList()
                .ForEach(type => builder.RegisterType(type)
                .SingleInstance()
                .PropertiesAutowired());


            assembly.GetTypes().Where(t => typeof(IHostedService).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass && !t.IsInterface)
                .ToList().ForEach((type) =>
                {
                    builder.RegisterType(type).As<IHostedService>().SingleInstance();
                    // 同时注册自身类型，以便其他组件可以依赖注入
                    builder.RegisterType(type).AsSelf().SingleInstance();
                });
        }
    }

    public interface IModuleRegister : IModule
    {
        public string SwaggerName { get; set; }

        public IEnumerable<Type> GetActionFilters();

        public Assembly GetAssembly();

        public List<Type> GetIBaseEntities();
    }
}
